package com.contact.util.util.collections;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.springframework.util.CollectionUtils;

//Helper class with lots of methods
public final class Utils extends CollectionUtils { //NOPMD

    private Utils() {
        //singleton
    }

    /* Common */

    public static int size(Collection<?> collection) {
        if (hasValues(collection)) {
            return collection.size();
        }
        return 0;
    }

    public static <T> boolean hasValues(T[] array) {
        return !isEmpty(array);
    }

    public static <T> boolean isEmpty(T[] array) {
        return array == null || array.length == 0;
    }

    public static boolean hasValues(Collection<?> collection) {
        return !isEmpty(collection);
    }

    public static boolean hasValues(Map<?, ?> map) {
        return !isEmpty(map);
    }

    public static <B> List<B> removeDuplicates(Collection<B> list) {
        return newArrayList(newLinkedHashSet(list));
    }

    /* Lists */

    public static <B> List<B> newArrayList() {
        return new ArrayList<B>();
    }

    public static <B> List<B> newArrayList(Collection<B> collection) {
        return new ArrayList<B>(collection);
    }

    public static <B> List<B> newArrayList(B... items) {
        return new ArrayList<B>(Arrays.asList(items));
    }

    /* Sets */

    public static <B> Set<B> newLinkedHashSet() {
        return new LinkedHashSet<B>();
    }

    public static <B> Set<B> newLinkedHashSet(Collection<B> collection) {
        return new LinkedHashSet<B>(collection);
    }

    public static <B> Set<B> newLinkedHashSet(B... items) {
        return new LinkedHashSet<B>(Arrays.asList(items));
    }

    public static <B> Set<B> newHashSet() {
        return new HashSet<B>();
    }

    public static <B> Set<B> newHashSet(Collection<B> collection) {
        return new HashSet<B>(collection);
    }

    public static <B> Set<B> newHashSet(B... items) {
        return new HashSet<B>(Arrays.asList(items));
    }

    public static <B> Set<B> newTreeSet() {
        return new TreeSet<B>();
    }

    public static <B> Set<B> newTreeSet(Comparator<B> comparator) {
        return new TreeSet<B>(comparator);
    }

    public static <B> Set<B> newTreeSet(Collection<B> collection) {
        return new TreeSet<B>(collection);
    }

    public static <B> Set<B> newTreeSet(B... items) {
        return new TreeSet<B>(Arrays.asList(items));
    }

    /* Maps */

    public static <K, V> Map<K, V> newHashMap() {
        return new HashMap<K, V>();
    }

    public static <K, V> Map<K, V> newHashMap(Map<? extends K, ? extends V> map) {
        return new HashMap<K, V>(map);
    }

    public static <K, V> Map<K, V> newLinkedHashMap() {
        return new LinkedHashMap<K, V>();
    }

    public static <K, V> Map<K, V> newLinkedHashMap(Map<? extends K, ? extends V> map) {
        return new LinkedHashMap<K, V>(map);
    }

    public static <K, V> Map<K, V> newTreeMap(Comparator<K> comparator) {
        return new TreeMap<K, V>(comparator);
    }

    public static <K, V> MultiMap<K, V> newLinkedMultiMap() {
        return new LinkedMultiMap<K, V>();
    }

    public static <K, T, V> MapsMap<K, T, V> newLinkedMapsMap() {
        return new LinkedMapsMap<K, T, V>();
    }

    public static <K, T, V> MapsMap<K, T, V> newConcurrentMapsMap() {
        return new ConcurrentMapsMap<K, T, V>();
    }

}
